package oauth

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"

	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/caddy/v2/modules/caddyhttp"
)

func init() {
	caddy.RegisterModule(OAuthMiddleware{})
}

// OAuthMiddleware 实现 OAuth 认证中间件
type OAuthMiddleware struct {
	Config *Config `json:"config,omitempty"`
}

// CaddyModule 返回 Caddy 模块信息
func (OAuthMiddleware) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "http.handlers.oauth",
		New: func() caddy.Module { return new(OAuthMiddleware) },
	}
}

// Provision 实现 caddy.Provisioner
func (m *OAuthMiddleware) Provision(ctx caddy.Context) error {
	if m.Config == nil {
		return fmt.Errorf("oauth configuration is required")
	}
	return m.Config.validateConfig()
}

// ServeHTTP 实现 HTTP 处理逻辑
func (m *OAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
	// 检查是否是排除路径
	if m.isExcludedPath(r.URL.Path) {
		return next.ServeHTTP(w, r)
	}

	// 检查是否是回调请求
	if r.URL.Path == m.Config.CallbackPath {
		return m.handleCallback(w, r)
	}

	// 验证JWT Token
	_, err := m.validateToken(r)
	if err != nil {
		// Token无效，重定向到授权页面
		return m.redirectToAuth(w, r)
	}

	// Token有效，继续处理请求
	return next.ServeHTTP(w, r)
}

// 检查是否是排除路径
func (m *OAuthMiddleware) isExcludedPath(path string) bool {
	for _, excludePath := range m.Config.ExcludePaths {
		if strings.HasPrefix(path, excludePath) {
			return true
		}
	}
	return false
}

// 重定向到授权页面
func (m *OAuthMiddleware) redirectToAuth(w http.ResponseWriter, r *http.Request) error {
	callbackURL := fmt.Sprintf("%s://%s%s",
		r.URL.Scheme,
		r.Host,
		m.Config.CallbackPath,
	)

	authURL := fmt.Sprintf("%s?client_id=%s&response_type=code&redirect_uri=%s&state=%s",
		m.Config.AuthorizeURL,
		m.Config.ClientID,
		url.QueryEscape(callbackURL),
		generateState(r),
	)

	http.Redirect(w, r, authURL, http.StatusTemporaryRedirect)
	return nil
}
